home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
001
/
modem.aqm
/
modem.asm
Wrap
Assembly Source File
|
1985-06-12
|
56KB
|
2,316 lines
TITLE MODEM FOR THE RAINBOW 100 SERIES WITH MS/DOS 2.05 +
Page 62,132
;
;****************************************************************
;* M O D E M - - FOR THE RAINBOW *
;* *
;* This program was developed from *
;* MODEM.ASM (Version 3.0) *
;* for CP/M to CP/M file transfers *
;* BY Ward Christensen (CPM-UG Disk # 25) *
;* Refer to the last section of this source file for *
;* a complete modification history and credits to *
;* those who contributed to this version. *
;* *
;* *
;* PLEASE SEND PROBLEM REPORTS AND SUGGESTIONS *
;* TO: John Chapman *
;* 844 S. Madison St. *
;* Hinsdale, Illinois 60521 *
;* Compuserve = 70205,1217 *
;* *
;* This version for the Digital Rainbow 100 computer with *
;* MS-DOS 2.05 + by James V. Colombo Rainbow SWE *
;* *
;****************************************************************
;
SUBTTL MACRO DEFINITIONS
PAGE
;
DOSCALL MACRO FUNCTION,AREA ;INVOKE DOS SERVICE
IFNB <AREA>
MOV DX,OFFSET AREA ;SET PARAMETER OFFSET
ENDIF
MOV AH,FUNCTION ;DOS FUNCTION CODE
INT 21H ;INVOKE DOS SERVICE
ENDM
;
PRCHAR MACRO CHAR ;PRINT A CHARACTER
IFNB <CHAR>
MOV DL,CHAR ;CHAR TO DL REG
ENDIF
DOSCALL DSPLO ; DOS PRINT CHARACTER FUNCTION
ENDM
;
SUBTTL STRUCTURES
PAGE
;
CCB STRUC
FUNCTION DB 0 ; function #
RETURN_CODE DB 0 ; return code
CHARACTER DB 0 ; character
CHAR_STATUS DB 0 ; character status
BUFFER DB 0 ; CCB or buffer
CCB ENDS
;
SUBTTL EQUATES
page
;
ROM EQU 18H
CR EQU 13
TAB EQU 9
LF EQU 10
PUTCHAR EQU 11
CANFLG EQU 0 ;NO CANCEL ABILITY
;
FASTCLK EQU 0 ;PUT 1 HERE FOR 4 MHZ CLOCK
ERRLIM EQU 10 ;MAX ALLOWABLE ERRORS
EXITCHR EQU 'W'-40H ;CTL-W EXIT FROM T OR C
DISCCHR EQU 'D'-40H ;CTL-D DISCONNECTS MODEM T/C
CTLCCHR EQU 'O'-40H ;CTL-C REPLACEMENT (temporary)
CTLCHAR EQU 03H ;CTL-C ACTUAL (temporary)
;
;DEFINE ASCII CHARACTERS USED
;
SOH EQU 01H ;START OF HEADER
EOT EQU 04H ;END OF TRANSMISSION
ACK EQU 06H ;ACKNOWLEDGE
NAK EQU 15H ;NEG ACKNOWLEDGE
CAN EQU 18H ;CANCEL
FF EQU 0CH ;FORM FEED (clear screen)
PAGE
;
; MS DOS EQUATES
;
REIPL EQU 0 ;PROGRAM TERMINATE
RDCON EQU 1 ;KEYBOARD INPUT
WRCON EQU 2 ;DISPLAY OUTPUT
PRTCHR EQU 5 ;PRINTER OUTPUT, CHAR IN DL
DCON EQU 6 ;DIRECT CONSOLE I/O
PRINT EQU 9 ;PRINT STRING
CONST EQU 11 ;CONSOLE STAT
OPEN EQU 15 ;0FFH=NOT FOUND
CLOSE EQU 16 ; " "
SRCHF EQU 17 ; " "
SRCHN EQU 18 ; " "
ERASE EQU 19 ;NO RET CODE
READ EQU 20 ;0=OK, 1=EOF
WRITE EQU 21 ;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC
MAKE EQU 22 ;0FFH=BAD
REN EQU 23 ;0FFH=BAD
STDMA EQU 26 ;SET DMA
FATADDR EQU 27 ;FILE ALLOCATION TABLE ADDRESS
;
; d o s f u n c t i o n s
;
DSPLO EQU 2
PSTRING EQU 9
DRESET EQU 0DH
SELDSK EQU 0EH
CDISK EQU 19H
SETDTA EQU 1AH
SETINTV EQU 25H
GETDATE EQU 2AH
GETTIME EQU 2CH
;
; MS DOS FCB EQUATES
;
INT20H EQU DS:00H
FCB EQU DS:5CH
FCBNAME EQU DS:5DH
FCBEXT EQU DS:65H
FCBSZL EQU DS:6CH
FCBSZH EQU DS:6DH
FCBCR EQU DS:7CH
FCBRR EQU DS:7DH
FCB2 EQU DS:6CH
;
B0050 EQU 1 ; 50 baud
B0075 EQU 2 ; 75 baud
B0110 EQU 3 ; 110 baud
B01345 EQU 4 ; 134.5 baud
B0150 EQU 5 ; 150 baud
B0200 EQU 6 ; 200 baud
B0300 EQU 7 ; 300 baud
B0600 EQU 8 ; 600 baud
B1200 EQU 9 ; 1200 baud
B1800 EQU 10 ; 1800 baud
B2000 EQU 11 ; 2000 baud
B2400 EQU 12 ; 2400 baud
B3600 EQU 13 ; 3600 baud
B4800 EQU 14 ; 4800 baud
B9600 EQU 16 ; 9600 baud
B19200 EQU 17 ; 19200 baud
;
SUBTTL 'PREFIX, CONSTANTS AND WORKAREA'
PAGE
MODEM SEGMENT PUBLIC 'CODE'
ASSUME CS:MODEM,DS:MODEM,ES:MODEM
;
; ----------------
; START OF ACTUAL PROGRAM AREA
; ----------------
ORG 100H
MAIN PROC FAR
JMP STARTS
OPTION DB 0 ;PRIMARY OPTION
;
;DATAFLG IS USED BY THE "V" SUBCOMMAND -
;IT IS 0 WHEN A HEADER OR CKSUM IS BEING
;SENT/RCD, AND 1 IF "VIEWABLE" DATA (THE
;SECTOR ITSELF) IS
;
DATAFLG DB 0 ;AT HEADER, FIRST
;
;
;SUB-OPTION TABLE. IF AN OPTION IS IN EFFECT,
; THE CHARACTER IS SET TO BINARY 0
;
OPTBL Label Word
ANSWFLG DB 'A' ;ANSWER MODE
DISCFLG DB 'D' ;DISCONNECT WHEN DONE
ECHOFLG DB 'E' ;TO ECHO AFTER XFER
DUMYFLG DB 'U' ;DEFAULT UART FLAG
INITFLG DB 'I' ;TO INIT THE UART / MODEM
ORIGFLG DB 'O' ;ORIGINATE MODE
QFLG DB 'Q' ;QUIET TRANSFER (NO MSGS)
RSEEFLG DB 'R' ;SEE WHAT'S RECEIVED
SSEEFLG DB 'S' ;SEE WHAT'S SENT
TERMFLG DB 'T' ;TO TERM AFTER XFER
VSEEFLG DB 'V' ;VIEW MESSAGES (NO HDR, ETC)
OPTBE Label Word ;END OF OPTIONS
;
TABLESIZE EQU OPTBE-OPTBL
;
RCVSNO DB 0 ;SECT # RECEIVED
SECTNO DB 0 ;CURRENT SECTOR NUMBER
ERRCT DB 0 ;ERROR COUNT
SAVCHAR DB 00 ;STORAGE FOR TERM
;
; FOLLOWING 3 USED BY DISK BUFFERING ROUTINES
;
EOFLG DB 0 ;EOF FLAG (1=TRUE)
SECPTR DW DBUF
SECINBF DB 0 ;# OF SECTORS IN BUFFER
;
bdtab db 010H ; 16 entries
db '020'
db b0200
db '110'
db b0110
db '120'
db b1200
db '134'
db b01345
db '150'
db b0150
db '180'
db b1800
db '192'
db b19200
db '200'
db b2000
db '240'
db b2400
db '300'
db b0300
db '360'
db b3600
db '480'
db b4800
db '50 '
db b0050
db '600'
db b0600
db '75 '
db b0075
db '960'
db b9600
;
; HELP MSGS
;
;
msg00 db cr,lf
db '+----------------------------------------------------------------+',cr,lf
db '| |',cr,lf
db '| M O D E M - - For the Rainbow 100 Series |',cr,lf
db '| Addapted by James V. Colombo Rainbow SWE |',cr,lf
db '| Version 3.3.4 |',cr,lf
db '| 01/18/85 |',cr,lf
db '+----------------------------------------------------------------+',cr,lf
db cr,lf,0,1
;
;
MSG01 DB CR,LF
; 1234567890123456789012345678901234567890123456789012345678901234567890
DB '---- M O D E M ---- ',cr,lf,cr,lf
db 'Converted from MODEM 3.0 by Ward Christensen ',cr,lf
DB 'Version 3.3.3 for The Rainbow by James V. Colombo',cr,lf
DB ' R E A D Y ',cr,lf
db cr,lf,'$',1,0
MSG01A DB 'File Open, Ready to Receive',CR,LF,0
MSG02 DB 'Awaiting #',0
MSG03A DB 'h rcd, not soh',CR,LF,0
MSG03 DB '+++ TIMEOUT +++',0
MSG04 DB '++ Bad Sector # in Hdr',CR,LF,0
MSG05 DB '++ CKSUM ++',0
MSG06 DB 'Send # ',0
MSG07 DB 'h rcvd, not ack ',CR,LF,0
MSG08 DB 'Timeout on ack',CR,LF,0
MSG09 DB 'Modem Program Cancelled ',CR,LF,0
MSG10 DB 'File exists, Type Y to erase ',0
MSG11 DB 'Can not open file$'
MSG12 DB 'File open, Extent Length ',0
MSG13 DB 'Awaiting Initial nak',CR,LF,0
MSG14 DB cr,lf,'Transfer Complete',CR,LF,0
MSG15 DB cr,lf,'Press Return to Disconnect'
DB cr,lf,'Press Space bar to Exit',0
MSG16 DB '++ EXITING ++',0
MSG17 DB cr,lf,'++ Do not Forget - The Modem is'
DB 'NOT Disconnected',CR,LF,0
; DB 'Use "M3 D" to Disconnect',CR,LF,0
MSG18 DB 'Multiple errors encountered. '
DB 'Type Q to quit, R to Retry ',0
MSG19 DB CR,LF,'Press Return to Continue'
DB CR,LF,0
MSG20 DB '++ Unable to Receive Block'
DB CR,LF,'++ ABORTING ++$'
MSG21 DB 'Can not Send Sector '
DB '- ABORTING',CR,LF,'$'
MSG22 DB '++ ERROR - Can not make file',CR,LF
DB '++ Directory must be full',CR,LF,'$'
MSG22A DB '++ Can not Close Files ++$'
MSG23 DB '++ File Read ERROR ++$'
MSG24 DB '++ ERROR Writing File ++',CR,LF,'$'
MSG25 DB 'Invalid option on modem command',CR,LF
DB 'PRESS RETURN FOR HELP, CTL-C IF NOT',CR,LF,1,0
MSG26 DB 'Format for command is',CR,LF,CR,LF
DB 'MODEM # FILENAME',CR,LF,CR,LF
DB 'Where # is a 1 character primary option,',CR,LF
DB ' which may be followed by sub-options,',CR,LF
DB ' and by ".xxx" to set baud rate to xxx'
DB CR,LF,CR,LF
DB 'Primary Options',CR,LF,1
DB ' S to send a file',CR,LF
DB ' R to receive a file',CR,LF
DB ' T to act as a terminal',CR,LF
DB ' E to act as a computer (echo data)',CR,LF
DB ' H to print this help file'
DB CR,LF,CR,LF
DB 'Secondary options',CR,LF,1
DB ' D disconnect after execution',CR,LF
DB ' T go to terminal mode after file xfer',CR,LF
DB ' E go to echo mode after file xfer',CR,LF
DB ' Q quiet mode - no status msgs',CR,LF
DB ' R show chars received',CR,LF
DB ' S show chars sent',CR,LF
DB ' V view file sent/received (no status)',CR,LF
DB CR,LF,'FOR EXAMPLES, TYPE MODEM X',CR,LF,1,0
MSG27 DB 'Send file, ',CR,LF
DB ' MODEM S fn.ft',CR,LF
DB 'Send another file',CR,LF
DB ' MODEM S fn.ft',CR,LF
DB 'Then send a third file at 450 baud and disconnect'
DB CR,LF,' MODEM SD.450 fn.ft',CR,LF
DB 'Act as a terminal (Default = 1200 baud) ',CR,LF
DB ' MODEM T',CR,LF
DB ' Use ctl-W to disonnect (drop DTR)',cr,lf
DB ' Use ctl-D to exit',CR,LF
DB 'Receive file, view it',CR,LF
DB ' MODEM RV fn.ft',CR,LF,1,0
;
DBUF DB 128*16 DUP(?) ;16 LOGICAL SECTOR BUFFER # 1
; (* Four physical sectors)
DB 128*16 DUP(?) ;16 LOGICAL SECTOR BUFFER # 2
; (* Four physical sectors)
; TOTAL = one track on PC/DOS (8/512)
; DB 'POOT'
INIT_CCB CCB <0,0,0,0,1> ; Initialization control block
mode db 1 ; Data Leads only
stop_bits db 1 ; One stop bit
bits db 4 ; Eight Bits
parit db 3 ; No Parity
brr db 9 ; Default to 1200 Baud - receive
brt db 9 ; Default to 1200 Baud - transmit
xon db 11H ; Xon character
xoff db 13H ; Xoff character
rxx db 2 ; Rx Auto Xon/Xoff
txx db 2 ; Tx Auto Xon/Xoff
bs dw 256 ; Size of comm buffer
boff dw 0 ; Comm_buffer offset
bsegm dw 0 ; Comm_buffer segment
;
IN_CCB CCB <7,0,0,0,0> ; Read input char
;
OUT_CCB CCB <10,0,0,0,0> ; Transmit character control block
;
MISC_CCB CCB <0,0,0,0,0> ; CCB for misc. use
;
SUBTTL 'MAIN PROGRAM SECTION'
PAGE
STARTS:
;
;=============================================================================
;
; PRINT THE STARTUP MESSAGE
;
push dx
MOV DX,OFFSET MSG01 ;GET ID MESSAGE
MOV CL,PRINT
CALL BDOS ;PRINT ID MESSAGE
pop dx
;
;=============================================================================
;
;
;SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT.
;
CALL PROCOPT
; IF WE RETURN FROM PROCOPT, A VALID
; ACTION OPTION (not help or examples)
; WAS FOUND .. PROCESSING CONTINUES
;
;INIT THE MODEM OR SERIAL PORT (dtr UP always - THEN CHECK FOR "i" OPT.
;
CALL INITMOD
;
;MOVE THE FILENAME FROM FCB 2 TO FCB 1
;
CALL MOVEFCB
;
;JMP TO APPROPRIATE FUNCTION
;
MOV AL,OPTION ;GET PRIMARY OPTION
;
CMP AL,'C' ;(COMPAT W/EARLIER
JNZ L00001
JMP TRMECHO ;OPTION "COMPUTER")
;
L00001: CMP AL,'E' ;TERMINAL IN ECHO
JNZ L00002
JMP TRMECHO ;..MODE?
;
L00002: CMP AL,'T' ;TERMINAL..
JNZ L00003
JMP TERM ;..MODE?
;
L00003:
; CMP AL,'D'
; JNZ L00004
; JMP DISCONN
;L00004:
;
CMP AL,'S' ;SEND..
JNZ L00005
JMP SENDFIL ;..A FILE?
;
L00005: CMP AL,'R' ;RECEIVE..
JNZ L00006
JMP RCVFIL ;..A FILE?
;
;INVALID OPTION
;
L00006: JMP BADOPT ;BAD OPTIONS !
;
; Return to MS-DOS after cleaning up the IOCTL drivers.
;
; Disable the receiver
;
EXIT:
;
; Now program the device to use the default buffer.
;
MOV Byte Ptr MISC_CCB.FUNCTION,05 ; Disable the receiver
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
MOV DX,OFFSET MISC_CCB ; DS:DX points to control block
INT 21H ; Call MS-DOS
MOV Byte Ptr MISC_CCB.FUNCTION,02 ; Use default buffer
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
MOV DX,OFFSET MISC_CCB ; DS:DX points to control block
INT 21H ; Call MS-DOS
;
; Reprogram driver to NVM values
;
MOV Byte Ptr MISC_CCB.FUNCTION,01 ; Reprogram to NVM value
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
MOV DX,OFFSET MISC_CCB ; DS:DX points to control block
INT 21H ; Call MS-DOS
;
; Now exit to MS-DOS
;
MOV AX,4C00H
INT 21H
MAIN ENDP
; * * * * * * * * * * * * * * * * * * * *
; *
; TERM: TERMINAL MODE *
; *
; * * * * * * * * * * * * * * * * * * * *
;
;THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS
;DOWN THE LINE, AND DISPLAYS CHARACTERS
;RECEIVED FROM THE LINE. THIS MAKES IT
;SUITABLE FOR COMMUNICATION WITH TIME SHARING
;COMPUTERS, CBBS'S, OR ANOTHER PROGRAM
;RUNING "MODEM E" (ECHO MODE)
;
;TYPEZZ THE "EXITCHR" (ORIGINALLY CTL-E) TO EXIT.
;OR THE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONN.
;
;A FUTURE ENHANCEMENT WILL BE TO WRITE THE
;RECEIVED DATA IN MEMORY, AND ALLOW IT TO
;BE WRITTEN TO DISK
;
TERM PROC NEAR
;
; See if there is a character available from the serial port
;
Call Statit ; Get status
Or Al,Al ; Character available?
Jz Terml ; If not, Loop
;
Call Getit ; Get character
CALL TYPEZZ ;TYPEZZ IT
;
Terml: Mov AL,Byte Ptr Savchar
OR AL,AL
Jnz L00009
Call Stat ; Get keyboard status
JNZ L00007 ; If so, get it!
JMP TERM ;..NO, CHECK LINE
L00007:
CALL KEYIN ;GET CHAR
CMP AL,EXITCHR ;TIME TO END?
JNZ L00008
JMP CKDIS ;YES, CK DISCONN
L00008:
CMP AL,DISCCHR ;DISCONNECT REQUEST?
JNZ L00009
JMP DISCONN ;YES, DO IT
L00009:
Mov Byte Ptr Savchar,00 ;Clear the saved character
Call Sendit ;Send character
Or Ah,Ah ;Was character sent?
Jne Term ;If so, loop
Mov Byte Ptr Savchar,AL
JMP TERM ;LOOP
TERM ENDP
;
; * * * * * * * * * * * * * * * * * * * *
; *
; TRMECHO: TERMINAL WITH ECHO *
; *
; * * * * * * * * * * * * * * * * * * * *
;
;TERMINAL PROGRAM WITH ECHO - SEE NOTES
;UNDER "TERM" ABOVE
;
;C A U T I O N DON'T RUN WITH BOTH COMPUTERS
;IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR)
;WILL BE ECHOED BACK AND FORTH AD INFINITUM.
;
TRMECHO PROC NEAR
Call Statit ;Get status
Or Al,Al ; Character available?
JZ L00011 ; If so, get it!
JMP LINECHR ;YES, READ THE CHR
L00011: CALL STAT ;CHECK LOCAL KB
JNZ L00012
JMP TRMECHO ;..NO CHAR
L00012: CALL KEYIN ;GET LOCAL CHAR
CMP AL,EXITCHR ;END?
JNZ L00013
JMP CKDIS ;YES, CK DISCONN, EXIT
L00013: CMP AL,DISCCHR ;DISCONN?
JNZ L00014
JMP DISCONN ;..YES, DO IT.
L00014: Call Sendit ;Send character
Or Ah,Ah ;Was character sent?
Jz L00014 ;If not, try again!
CALL TYPEZZ ;ECHO IT LOCALLY
JMP TRMECHO ;..AND LOOP
;
;GOT CHAR FROM LINE
;
LINECHR:
Call Getit ; Get character
CALL TYPEZZ ;TYPEZZ IT
JMP TRMECHO ;LOOP
TRMECHO ENDP
;
; * * * * * * * * * * * * * * * * * * * *
; *
; SENDFIL: SENDS A CP/M FILE *
; *
; * * * * * * * * * * * * * * * * * * * *
;
;THE CP/M FILE SPECIFIED IN THE MODEM COMMAND
;IS TRANSFERRED OVER THE PHONE TO ANOTHER
;COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE)
;OPTION. THE DATA IS SENT ONE SECTOR AT A
;TIME WITH HEADERS AND CHECKSUMS, AND RE-
;TRANSMISSION ON ERRORS.
;
SENDFIL PROC NEAR
;
; Turn off auto Xon/Xoff
;
Mov Rxx,01h ; Disable Rx Auto Xon
Mov Txx,01h ; Disable Tx Auto Xon
MOV DX,OFFSET INIT_CCB ; DS:DX points to control block
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
INT 21H ; Call MS-DOS
;
CALL OPENFIL ;OPEN THE FILE
MOV DL,80 ;WAIT 80 SEC..
CALL WAITNAK ;..FOR INITIAL NAK
SENDLP: CALL RDSECT ;READ A SECTOR
JAE L00016
JMP SENDEOF ;SEND EOF IF DONE
L00016: CALL INCRSNO ;BUMP SECTOR #
XOR AL,AL ;ZERO ERROR..
MOV ERRCT,AL ;..COUNT
SENDRPT:
CALL SENDHDR ;SEND A HEADER
CALL SENDSEC ;SEND DATA SECTOR
CALL SENDCKS ;SEND CKSUM
CALL GETACK ;GET THE ACK
JAE L00017
JMP SENDRPT ;REPEAT IF NO ACK
L00017: JMP SENDLP ;LOOP UNTIL EOF
;
;FILE SENT, SEND EOT'S
;
SENDEOF:
MOV AL,EOT ;SEND..
CALL SEND ;..AN EOT
CALL GETACK ;GET THE ACK
JAE L00018
JMP SENDEOF ;LOOP IF NO ACK
;
; Turn on auto Xon/Xoff
;
L00018: Mov Rxx,02h ; Enable Rx Auto Xon
Mov Txx,02h ; Enable Tx Auto Xon
MOV DX,OFFSET INIT_CCB ; DS:DX points to control block
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
INT 21H ; Call MS-DOS
JMP DONE ;ALL DONE
;
SENDFIL ENDP
;
; * * * * * * * * * * * * * * * * * * * *
; *
; RCVFIL: RECEIVE A FILE *
; *
; * * * * * * * * * * * * * * * * * * * *
;
;RECEIVES A FILE IN BLOCK FORMAT AS SENT
;BY ANOTHER PERSON DOING "MODEM S FN.FT".
;
RCVFIL PROC NEAR
;
; Turn off auto Xon/Xoff
;
Mov Rxx,01h ; Disable Rx Auto Xon
Mov Txx,01h ; Disable Tx Auto Xon
MOV DX,OFFSET INIT_CCB ; DS:DX points to control block
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
INT 21H ; Call MS-DOS
;
CALL ERASFIL ;ERASE THE FILE
CALL MAKEFIL ;..THEN MAKE NEW
MOV AL,QFLG ;SEE IF IN QUIET MODE
OR AL,AL
JZ L00019
JMP RCVLP ;NOT IN QUIET MODE, SKIP MSG
L00019: PUSH BX
MOV BX,OFFSET MSG01A
CALL ILPRT ;PRINT:
POP BX
RCVLP: CALL RCVSECT ;GET A SECTOR
JAE L00020
JMP RCVEOT ;GOT EOT
L00020: CALL WRSECT ;WRITE THE SECTOR
CALL INCRSNO ;BUMP SECTOR #
CALL SENDACK ;ACK THE SECTOR
JMP RCVLP ;LOOP UNTIL EOF
;
;GOT EOT ON SECTOR - FLUSH BUFFERS, END
;
RCVEOT: CALL WRBLOCK ;WRITE THE LAST BLOCK
CALL SENDACK ;ACK THE SECTOR
CALL CLOSFIL ;CLOSE THE FILE
;
;
; Turn on auto Xon/Xoff
;
Mov Rxx,02h ; Enable Rx Auto Xon
Mov Txx,02h ; Enable Tx Auto Xon
MOV DX,OFFSET INIT_CCB ; DS:DX points to control block
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
INT 21H ; Call MS-DOS
;
MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ L00021
JMP CKDIS ;YES, CK DISCONN, END.
L00021: JMP DONE ;DISCONN IF REQ'D
RCVFIL ENDP
;
; * * * * * * * * * * * * * * * * * * * *
; *
; SUBROUTINES *
; *
; * * * * * * * * * * * * * * * * * * * *
;
;
;----> RCVSECT: RECEIVE A SECTOR
;
;RETURNS WITH CARRY SET IF EOT RECEIVED.
;
RCVSECT PROC NEAR
XOR AL,AL ;GET 0
MOV ERRCT,AL ;INIT ERROR COUNT
RCVRPT: MOV AL,QFLG ;QUIET?
OR AL,AL
JNZ L00022
JMP RCVSQ ;YES, NO STAT MSG.
L00022: PUSH BX
MOV BX,OFFSET MSG02
CALL ILPRT ;PRINT:
POP BX
MOV AL,SECTNO ;GET SECTOR #
INC AL ;(REAL INR LATER)
CALL HEXO ;PRINT IN HEX
CALL CRLF ;..THEN CRLF
;
RCVSQ: MOV CH,10 ;10 SEC TIMEOUT
CALL RECV ;GET SOH/EOT
JAE L00023
JMP RCVSTOT ;TIMEOUT
L00023: CMP AL,SOH ;GET SOH?
JNZ L00024
JMP RCVSOH ;..YES
;
;EARLIER VERS. OF MODEM PROG SENT SOME NULLS -
;IGNORE THEM
;
L00024: OR AL,AL ;00 FROM SPEED CHECK?
JNZ L00025
JMP RCVSQ ;YES, IGNORE IT
L00025: CMP AL,EOT ;END OF TRANSFER?
STC ;RETURN WITH CARRY..
JNZ L00026
RET ;..SET IF EOT
;
;DIDN'T GET SOH OR EOT -
;
L00026: MOV CH,AL ;SAVE CHAR
MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..MODE?
JNZ L00027
JMP RCVSEH ;YES, PRT.MSG
L00027: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ RCVSEH
JMP RCVSERR ;YES, SKIP MSG
RCVSEH: MOV AL,CH ;GET CHAR
CALL HEXO ;SHOW IN HEX
PUSH BX
MOV BX,OFFSET MSG03
CALL ILPRT ;PRINT:
POP BX
;
;DIDN'T GET VALID HEADER - PURGE THE LINE,
;THEN SEND NAK.
;
RCVSERR:
MOV CH,1 ;WAIT FOR 1 SEC..
CALL RECV ;..WITH NO CHARS
JNAE L00029
JMP RCVSERR ;LOOP UNTIL SENDER DONE
L00029: MOV AL,NAK ;SEND..
CALL SEND ;..THE NAK
MOV AL,ERRCT ;ABORT IF..
INC AL ;..WE HAVE REACHED..
MOV ERRCT,AL ;..THE ERROR..
CMP AL,ERRLIM ;..LIMIT?
JAE L00030
JMP RCVRPT ;..NO, TRY AGAIN
;
;10 ERRORS IN A ROW -
;
L00030: MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..FILE?
JNZ L00031
JMP RCVCKQ ;YES, ASK RETRY/QUIT
L00031: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ RCVCKQ
JMP RCVSABT ;ABORT
RCVCKQ: CALL CKQUIT ;RETRY/QUIT?
JNZ RCVSABT
JMP RCVSECT ;TRY AGAIN
;
RCVSABT:
CALL CLOSFIL ;KEEP WHATEVER WE GOT
MOV DX,OFFSET MSG20
CALL ERXIT
;
;TIMEDOUT ON RECEIVE
;
RCVSTOT:
STI
MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..MODE?
JNZ L00034
JMP RCVSPT ;YES, PRT MSG
L00034: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ RCVSPT
JMP RCVSERR ;YES, NO MSG
RCVSPT: PUSH BX
MOV BX,OFFSET MSG03
CALL ILPRT
POP BX
RCVPRN: MOV AL,ERRCT ;PRINT ERROR..
CALL HEXO ;..COUNT
CALL CRLF
JMP RCVSERR ;BUMP ERR CT, ETC.
;
;GOT SOH - GET BLOCK #, BLOCK # COMPLEMENTED
;
RCVSOH: MOV CH,1 ;TIMEOUT = 1 SEC
CALL RECV ;GET SECTOR
JAE L00036
JMP RCVSTOT ;GOT TIMEOUT
L00036: MOV DH,AL ;D=BLK #
MOV CH,1 ;TIMEOUT = 1 SEC
CALL RECV ;GET CMA'D SECT #
JAE L00037
JMP RCVSTOT ;TIMEOUT
L00037: NOT AL ;CALC COMPLEMENT
CMP AL,DH ;GOOD SECTOR #?
JNZ L00038
JMP RCVDATA ;YES, GET DATA
;
;GOT BAD SECTOR #
;
L00038: MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..MODE?
JNZ L00039
JMP RCVBSE ;..YES, PRT MSG
L00039: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ RCVBSE
JMP RCVSERR ;..YES, NO MSG
;
RCVBSE: PUSH BX
MOV BX,OFFSET MSG04
CALL ILPRT ;PRINT:
POP BX
JMP RCVSERR ;BUMP ERROR CT.
;
;
RCVDATA:
MOV AL,DH ;GET SECTOR #
MOV RCVSNO,AL ;SAVE IT
MOV AL,1 ;SHOW..
MOV DATAFLG,AL ;GETTING DATA
MOV CL,0 ;INIT CKSUM
MOV BX,80H ;POINT TO BUFFER
CLI
RCVCHR: MOV CH,1 ;1 SEC TIMEOUT
CALL RECV ;GET CHAR
JAE L00041
JMP RCVSTOT ;TIMEOUT
L00041: MOV BYTE PTR [BX],AL ;STORE CHAR
INC BL ;DONE?
JZ L00042
JMP RCVCHR ;NO, LOOP
;
;VERIFY CHECKSUM
;
L00042: MOV DH,CL ;SAVE CHECKSUM
XOR AL,AL ;SHOW..
MOV DATAFLG,AL ;..END OF DATA
MOV CH,1 ;TIMEOUT LEN.
CALL RECV ;GET CHECKSUM
JAE L00043
JMP RCVSTOT ;TIMEOUT
L00043: STI
CMP AL,DH ;CHECKSUM OK?
JZ L00044
JMP RCVCERR ;NO, ERROR
;
;GOT A SECTOR, IT'S A DUP IF = PREV,
; OR OK IF = 1 + PREV SECTOR
;
L00044: MOV AL,RCVSNO ;GET RECEIVED
MOV CH,AL ;SAVE IT
MOV AL,SECTNO ;GET PREV
CMP AL,CH ;PREV REPEATED?
JNZ L00045
JMP RECVACK ;ACK TO CATCH UP
L00045: INC AL ;CALC NEXT SECTOR #
CMP AL,CH ;MATCH?
JZ L00046
JMP ABORT ;NO MATCH - STOP SENDER, EXIT
L00046: RET ;CARRY OFF - NO ERRORS
;
;GOT CKSUM
;
RCVCERR:
MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..MODE?
JNZ L00047
JMP RCVCPR ;..YES, PRT MSG
L00047: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ RCVCPR
JMP RCVSERR ;YES, NO MSG
RCVCPR: PUSH BX
MOV BX,OFFSET MSG05
CALL ILPRT
POP BX
JMP RCVPRN ;PRINT ERROR #
;
;PREV SECT REPEATED, DUE TO THE LAST ACK
;BEING GARBAGED. ACK IT SO SENDER WILL CATCH UP
;
RECVACK:
CALL SENDACK ;SEND THE ACK,
JMP RCVSECT ;GET NEXT BLOCK
;
;SEND AN ACK FOR THE SECTOR
;
SENDACK:
MOV AL,ACK ;GET ACK
CALL SEND ;..AND SEND IT
RET
RCVSECT ENDP
;
;----> SENDHDR: SEND THE SECTOR HEADER
;
;SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #)
;
SENDHDR PROC NEAR
MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ L00049
JMP SENDHNM ;YES, SKIP STATUS MSG.
L00049: PUSH BX
MOV BX,OFFSET MSG06
CALL ILPRT ;PRINT:
POP BX
MOV AL,SECTNO ;PRINT..
CALL HEXO ;..SECT #
CALL CRLF ;..THEN CR/LF
;
SENDHNM:
MOV AL,SOH ;SEND..
CALL SEND ;..SOH,
MOV AL,SECTNO ;THEN SEND..
CALL SEND ;..SECTOR #
MOV AL,SECTNO ;THEN SENDOR #
NOT AL ;..COMPLEMENTED..
CALL SEND ;..SECTOR #
RET ;FROM SENDHDR
SENDHDR ENDP
;
;----> SENDSEC: SEND THE DATA SECTOR
;
;WHILE SENDING THE SECTOR, THE "DATAFLG" IS SET
;SUCH THAT IF "V" (VIEW THE FILE) WAS REQUESTED,
;THE "SHOW" ROUTINE WILL PRINT THE DATA, BUT NOT
;THE HDR OR CKSUM, OR ANY NON-FATAL MSGS.
;
SENDSEC PROC NEAR
MOV AL,1 ;SHOW NOW AT DATA..
MOV DATAFLG,AL ;..FOR VIEW COMMAND
MOV CL,0 ;INIT CKSUM
MOV BX,80H ;POINT TO BUFFER
SENDC: MOV AL,BYTE PTR [BX] ;GET A CHAR
CALL SEND ;SEND IT
INC BL ;POINT TO NEXT CHAR
JZ L00050
JMP SENDC ;LOOP IF <100H
L00050: XOR AL,AL ;SHOW NOT INTO DATA..
MOV DATAFLG,AL ;..FOR VIEW COMMAND
RET ;FROM SENDSEC
SENDSEC ENDP
;
;----> SENDCKS: SEND THE CHECKSUM
;
SENDCKS PROC NEAR
MOV AL,CL ;SEND THE..
CALL SEND ;..CHECKSUM
RET ;FROM SENDCKS
SENDCKS ENDP
;
;----> GETACK: GET THE ACK ON THE SECTOR
;
;RETURNS WITH CARRY CLEAR IF ACK RECEIVED.
;IF AN ACK IS NOT RECEIVED, THE ERROR COUNT
;IS INCREMENTED, AND IF LESS THAN "ERRLIM",
;CARRY IS SET AND CONTROL RETURNS. IF THE
;ERROR COUNT IS AT "ERRLIM", THE PROGRAM
;ABORTS IF IN "QUIET" MODE, OR ASKS THE
;USER FOR QUIT/RETRY IF NOT.
;
GETACK PROC NEAR
MOV CH,10 ;WAIT 10 SECONDS MAX
CALL RECVDG ;RECV W/GARBAGE COLLECT
JAE L00051
JMP GESATOT ;TIMED OUT
L00051: CMP AL,ACK ;OK? (CARRY OFF IF =)
JNZ L00052
RET ;YES, RET FROM GETACK
;
L00052 LABEL NEAR
IF CANFLG
CMP AL,CAN ;CANCEL TRANSMISSION?
JNZ L00053
JMP ABORT ;..YES
L00053 LABEL NEAR
ENDIF
;
MOV CH,AL ;SAVE CHAR
MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ L00054
JMP ACKERR ;..YES, NO MSG
L00054: MOV AL,CH ;GET CHAR
CALL HEXO ;PRINT IN HEX
PUSH BX
MOV BX,OFFSET MSG07
CALL ILPRT ;PRINT:
POP BX
;
;TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT
;
ACKERR: MOV AL,ERRCT ;GET COUNT
INC AL ;BUMP IT
MOV ERRCT,AL ;SAVE BACK
CMP AL,ERRLIM ;AT LIMIT?
JNB L00055
RET ;NOT AT LIMIT
;
;REACHED ERROR LIMIT
;
L00055: MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..FILE?
JNZ L00056
JMP GACKV ;YES, ASK QUIT/RETRY
L00056: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ GACKV
JMP CSABORT ;..YES, NO MCG
GACKV: CALL CKQUIT ;SEE IF WANT TO QUIT
STC ;TO SHOW NO ACK
JNZ CSABORT
RET ;KEEP ON TRYIN'
CSABORT:
MOV DX,OFFSET MSG21
CALL ERXIT
GETACK ENDP
;
;TIMEOUT GETTING ACK
;
GESATOT PROC NEAR
MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ L00059
JMP ACKERR ;YES, NO MSG
L00059: PUSH BX
MOV BX,OFFSET MSG08
CALL ILPRT ;PRINT:
POP BX
JMP ACKERR
GESATOT ENDP
;
;----> CKABORT: CHECK FOR LOCAL ABORT
;
;IF THE USER WANTS TO CANCEL THE TRANSMISSION,
;TYPING CTL-X WILL ABORT IT. NOTE THIS TEST
;IS NOT MADE IF IN QUIET (NO CONSOLE I/O) MODE.
;
CKABORT PROC NEAR
MOV AL,VSEEFLG ;VIEWING?
OR AL,AL
JNZ L00060
JMP CKABGO ;YES, CHECK
L00060: MOV AL,QFLG ;SUPPRESSED..
OR AL,AL ;..CONSOLE I/O?
JNZ L00061
RET ;YES, NO TEST
;
L00061 LABEL NEAR
IF NOT CANFLG
RET
ENDIF
;
CKABGO: CALL STAT ;KEY PRESSED?
JNZ L00062
RET ;NOTHING FROM KEYBOARD
L00062: CALL KEYIN ;GET DATA
CMP AL,EXITCHR ;TIME TO END?
JZ ABORT
RET ;NO, CONTINUE
;
ABORT: NOP ;LEA SP,STACK
ABORTL: MOV CH,1 ;1 SEC. W/O CHARS.
CALL RECV
JNAE L00064
JMP ABORTL ;LOOP UNTIL SENDER DONE
L00064: MOV AL,CAN ;CONTROL X
CALL SEND ;STOP SENDING END
ABORTW: MOV CH,1 ;1 SEC W/O CHARS.
CALL RECV
JNAE L00065
JMP ABORTW ;LOOP UNTIL SENDER DONE
L00065: MOV AL,' ' ;GET A SPACE...
CALL SEND ;TO CLEAR OUT CONTROL X
PUSH BX
MOV BX,OFFSET MSG09
CALL ILPRT ;EXIT WITH ABORT MSG
POP BX
JMP CKDIS ;CHECK FOR DISCONN.
CKABORT ENDP
;
;----> INCRSNO: INCREMENT SECTOR #
;
INCRSNO PROC NEAR
MOV AL,SECTNO ;INCR..
INC AL ;..SECT..
MOV SECTNO,AL ;..NUMBER
RET
INCRSNO ENDP
;
;----> ERASFIL: ERASE THE INCOMING FILE.
;
;IF IT EXISTS, ASK IF IT MAY BE ERASED.
;
ERASFIL PROC NEAR
MOV DX,OFFSET FCB ;POINT TO CTL BLOCK
MOV CL,SRCHF ;SEE IF IT..
CALL BDOS ;..EXISTS
INC AL ;FOUND?
JNZ L00066
RET ;..NO, RETURN
L00066: PUSH BX
MOV BX,OFFSET MSG10
CALL ILPRT ;PRINT:
POP BX
CALL KEYIN ;GET CHAR
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH
CALL TYPEZZ ;ECHO
POP AX
XCHG AL,AH
SAHF
AND AL,5FH ;MAKE UPPER CASE
CMP AL,'Y' ;WANT ERASED?
JZ L00067
JMP CKDIS ;QUIT IF NOT ERASE
L00067: CALL CRLF ;BACK TO START OF LINE
;
;ERASE OLD FILE
;
MOV DX,OFFSET FCB ;POINT TO FCB
MOV CL,ERASE ;GET BDOS FNC
CALL BDOS ;DO THE ERASE
RET ;FROM "ERASFIL"
ERASFIL ENDP
;
;----> MAKEFIL: MAKES THE FILE TO BE RECEIVED
;
MAKEFIL PROC NEAR
MOV DX,OFFSET FCB ;POINT TO FCB
MOV CL,MAKE ;GET BDOS FNC
CALL BDOS ;TO THE MAKE
INC AL ;FF=BAD?
JZ L00068
RET ;OPEN OK
;DIRECTORY FULL - CAN'T MAKE FILE
L00068: MOV DX,OFFSET MSG22
CALL ERXIT
MAKEFIL ENDP
;
;----> OPENFIL: OPENS THE FILE TO BE SENT
;
OPENFIL PROC NEAR
MOV DX,OFFSET FCB ;POINT TO FILE
MOV CL,OPEN ;GET FUNCTION
CALL BDOS ;OPEN IT
INC AL ;OPEN OK?
JZ L00069
JMP OPENOK ;..YES
L00069: PUSH DX
MOV DX,OFFSET MSG11
CALL ERXIT ;..NO, ABORT
POP DX
;
OPENOK:
PUSH BX
MOV BX,OFFSET MSG12
CALL ILPRT ;PRINT:
POP BX
MOV AL,FCBSZH ;GET FILE SIZE HIGH ORDER
CALL HEXO ;PRINT IN HEX
MOV AL,FCBSZL ;GET FILE SIZE LOW ORDER
CALL HEXO ;PRINT IN HEX
MOV AL,'H'
CALL TYPEZZ ;PRINT 'H' AFTER NUMBER
CALL CRLF ;..THEN CRLF
RET
OPENFIL ENDP
;
;----> CLOSFIL: CLOSES THE RECEIVED FILE
;
CLOSFIL PROC NEAR
MOV DX,OFFSET FCB ;POINT TO FILE
MOV CL,CLOSE ;GET FUNCTION
CALL BDOS ;CLOSE IT
INC AL ;CLOSE OK?
JZ L00070
RET ;..YES, RETURN
L00070: MOV DX,OFFSET MSG22A
CALL ERXIT ;..NO, ABORT
CLOSFIL ENDP
;
;----> RDSECT: READS A SECTOR
;
;FOR SPEED, THIS ROUTINE BUFFERS UP 16
;SECTORS AT A TIME.
;
RDSECT PROC NEAR
MOV AL,SECINBF ;GET # SECT IN BUFF.
DEC AL ;DECREMENT..
MOV SECINBF,AL ;..IT
JNS L00071
JMP RDBLOCK ;EXHAUSTED? NEED MORE.
L00071: MOV BX,SECPTR ;GET POINTER
MOV DX,80H ;TO DATA
CALL MOVE128 ;MOVE TO BUFFER
MOV SECPTR,BX ;SAVE BUFFER POINTER
RET ;FROM "READSEC"
;
;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 16
;
RDBLOCK LABEL NEAR
MOV AL,EOFLG ;GET EOF FLAG
CMP AL,1 ;IS IT SET/
STC ;TO SHOW EOF
JNZ L00072
RET ;GOT EOF
L00072: MOV CL,0 ;SECTORS IN BLOCK
LEA DX,DBUF ;TO DISK BUFFER
RDSECLP LABEL NEAR
PUSH CX
PUSH DX
MOV CL,STDMA ;SET DMA..
CALL BDOS ;..ADDR
MOV DX,OFFSET FCB
MOV CL,READ
CALL BDOS
POP DX
POP CX
OR AL,AL ;READ OK?
JNZ L00073
JMP RDSECOK ;YES
L00073: DEC AL ;EOF?
JZ REOF ; 1 = EOF (regular)
DEC AL
JZ L00074 ; 2 = ERROR (trans area too small)
DEC AL
JZ RDSECOK ; 3 = EOF (partial block)
; ALL OTHER RETURNS CONSIDERED ERROR !!!
;
;READ ERROR
;
L00074: MOV DX,OFFSET MSG23
CALL ERXIT
;
RDSECOK:
MOV BX,80H
PUSH SI
PUSHF
ADD BX,DX
RCR SI,1
POPF
RCL SI,1
POP SI ;TO NEXT BUFF
XCHG BX,DX ;BUFF TO DE
INC CL ;MORE SECTORS?
MOV AL,CL ;GET COUNT
CMP AL,16 ;DONE?
JNZ L00075
JMP RDBFULL ;..YES, BUFF IS FULL
L00075: JMP RDSECLP ;READ MORE
;
REOF: MOV AL,1
MOV EOFLG,AL ;SET EOF FLAG
MOV AL,CL
;
;BUFFER IS FULL, OR GOT EOF
;
RDBFULL:
MOV SECINBF,AL ;STORE SECTOR COUNT
MOV BX,OFFSET DBUF ;INIT BUFFER..
MOV SECPTR,BX ;..POINTER
MOV DX,80H ;RESET..
MOV CL,STDMA ;..DMA..
CALL BDOS ;..ADDR
JMP RDSECT ;PASS SECT TO CALLER
RDSECT ENDP
;
;----> WRSECT: WRITE A SECTOR
;
;WRITES THE SECTOR INTO A BUFFER. WHEN 16
;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
;
;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
;
WRSECT PROC NEAR
MOV BX,SECPTR ;GET BUFF ADDR
XCHG BX,DX ;TO DE FOR MOVE
MOV BX,80H ;FROM HERE
CALL MOVE128 ;MOVE TO BUFFER
XCHG BX,DX ;SAVE NEXT..
MOV SECPTR,BX ;..BLOCK POINTER
MOV AL,SECINBF ;BUMP THE..
INC AL ;..SECTOR #..
MOV SECINBF,AL ;..IN THE BUFF
CMP AL,16 ;HAVE WE 16?
JZ WRBLOCK
RET ;NO, RETURN
;
;----> WRBLOCK: WRITES A BLOCK TO DISK
;
WRBLOCK:
MOV AL,SECINBF ;# SECT IN BUFFER
OR AL,AL ;0 MEANS END OF FILE
JNZ L00077
RET ;NONE TO WRITE
L00077: MOV CL,AL ;SAVE COUNT
LEA DX,DBUF ;POINT TO DISK BUFF
DKWRLP: PUSH BX
PUSH DX
PUSH CX
MOV CL,STDMA ;SET DMA
CALL BDOS ;TO BUFFER
MOV DX,OFFSET FCB ;THEN WRITE
MOV CL,WRITE ;..THE..
CALL BDOS ;..BLOCK
POP CX
POP DX
POP BX
OR AL,AL
JZ L00078
JMP WRERR ;OOPS, ERROR
L00078: MOV BX,80H ;LENGTH OF 1 SECT
PUSH SI
PUSHF
ADD BX,DX
RCR SI,1
POPF
RCL SI,1
POP SI ;HL= NEXT BUFF
XCHG BX,DX ;TO DE FOR SETDMA
DEC CL ;MORE SECTORS?
JZ L00079
JMP DKWRLP ;..YES, LOOP
L00079: XOR AL,AL ;GET A ZERO
MOV SECINBF,AL ;RESET # OF SECTORS
MOV BX,OFFSET DBUF ;RESET BUFFER..
MOV SECPTR,BX ;..POINTER
;
MOV DX,80H ;07/13/79 MOD..
MOV CL,STDMA ;..TO RESET..
CALL BDOS ;..DMA ADDR.
;
RET
;
WRERR: MOV CL,CAN ;CANCEL..
CALL SEND ;..SENDER
MOV DX,OFFSET MSG24
CALL ERXIT ;EXIT W/MSG:
WRSECT ENDP
;
;----> RECV: RECEIVE A CHARACTER
;
;TIMEOUT TIME IS IN B, IN SECONDS. ENTRY VIA
;"RECVDG" DELETES GARBAGE CHARACTERS ON THE
;LINE. FOR EXAMPLE, HAVING JUST SENT A SECTOR,
;CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED
;CHARACTERS "LONG" BEFORE THE ACK/NAK WOULD
;BE RECEIVED.
;
RECCHAR PROC NEAR
RECVDG LABEL NEAR ;RECEIVE W/GARBAGE DELETE
RECV: PUSH DX ;SAVE
;
IF FASTCLK ;4MHZ?
MOV AL,CH ;GET TIME REQUEST
ADD AL,AL ;DOUBLE IT
MOV CH,AL ;NEW TIME IN B
ENDIF
;
MSEC: MOV DX,200h ;1 SEC DCR COUNT
CALL CKABORT ;CHECK FOR EXIT REQUEST
MWTI: Call Statit ; Get status
Or Al,Al ; Character Available?
JZ L00080
JMP MCHAR ;GOT CHAR
L00080: DEC DL ;COUNT..
JZ L00081
JMP MWTI ;..DOWN..
L00081: DEC DH ;..FOR..
JZ L00082
JMP MWTI ;..TIMEOUT
L00082: DEC CH ;MORE SECONDS?
JZ L00083
JMP MSEC ;YES, WAIT
;
;MODEM TIMED OUT RECEIVING
;
L00083: POP DX ;RESTORE D,E
STC ;CARRY SHOWS TIMEOUT
RET
;
;GOT CHAR FROM MODEM
;
MCHAR: Call Getit ; Get character
POP DX ;RESTORE DE
;
;CALC CHECKSUM
;
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;SAVE THE CHAR
ADD AL,CL ;ADD TO CHECKSUM
MOV CL,AL ;SAVE CHECKSUM
;
;CHECK IF MONITORING REC'D DATA
;
MOV AL,RSEEFLG ;SEE RECEIVED..
OR AL,AL ;..DATA?
JNZ L00084
JMP MONIN ;..YES
;
;CHECK IF "VIEWING" AND THIS IS A DATA CHAR
;
L00084: MOV AL,VSEEFLG ;VIEWING..
OR AL,AL ;..DATA?
JZ L00085
JMP NOMONIN ;..NO
;
;"VIEW" REQUESTED. SHOW THE CHAR IT IS DATA
;
L00085: MOV AL,DATAFLG ;GET DATA FLAG
OR AL,AL ;TEST IT
JNZ MONIN
JMP NOMONIN ;..OFF, NOT DATA
MONIN: POP AX
XCHG AL,AH
SAHF ;..IS DATA,
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;GET IT,
CALL SHOW ;..AND SHOW IT
NOMONIN:
POP AX
XCHG AL,AH
SAHF ;RESTORE CHAR
OR AL,AL ;CARRY OFF: NO ERROR
RET ;FROM "RECV"
RECCHAR ENDP
;
;----> SEND: SEND A CHARACTER TO THE MODEM
;
SEND PROC NEAR
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;SAVE THE CHAR
;
;CHECK IF MONITORING SENT DATA
;
MOV AL,SSEEFLG ;CHECK IF MONITORING..
OR AL,AL ;..SENT DATA
JNZ L00087
JMP MONOUT ;..YES
;
;CHECK IF "VIEWING" THE FILE
;
L00087: MOV AL,VSEEFLG ;GET VIEW FLAG
OR AL,AL ;TEST IT
JZ L00088
JMP NOMONOT ;NO
L00088: MOV AL,DATAFLG ;IS THIS
OR AL,AL ;..DATA?
JNZ MONOUT
JMP NOMONOT ;..NO.
MONOUT: POP AX
XCHG AL,AH
SAHF ;GET THE CHAR
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;SAVE IT
CALL SHOW ;SHOW IT
NOMONOT:
POP AX
XCHG AL,AH
SAHF ;RESTORE CHAR
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;SAVE IT
ADD AL,CL ;CALC CKSUM
MOV CL,AL ;SAVE CKSUM
Pop Ax
Xchg Al,Ah
Sahf
Sendl: Call Sendit ;Send character
Or Ah,Ah ;Was character sent
Jz Sendl ;If not, try again!
RET ;FROM "SEND"
SEND ENDP
;
;----> WAITNAK: WAITS FOR INITIAL NAK
;
;TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING
;PROGRAM IS READY, THIS ROUTINE WAITS FOR THE
;THE FIRST TIMEOUT-NAK FROM THE RECEIVER. (E)
;CONTAINS THE # OF SECONDS TO WAIT.
;
WAITNAK PROC NEAR
MOV AL,VSEEFLG ;VIEWING?
OR AL,AL
JNZ L00091
JMP WAITNPR ;PRINT MSG
L00091: MOV AL,QFLG ;QUIET..
OR AL,AL ;..MODE?
JNZ WAITNPR
JMP WAITNLP ;YES, SKIP MSG
WAITNPR LABEL NEAR
PUSH BX
MOV BX,OFFSET MSG13
CALL ILPRT ;PRINT:
POP BX
WAITNLP LABEL NEAR
CALL CKABORT ;ABORT IF LOCAL CTL-X
MOV CH,1 ;TIMEOUT DELAY
CALL RECV ;DID WE GET..
CMP AL,NAK ;..A NAK?
JNZ L00093
RET ;YES, SEND BLOCK
;
L00093 LABEL NEAR
IF CANFLG
CMP AL,CAN ;CTL-X FROM REMOTE?
JNZ L00094
JMP ABORT ;..YES, ABORT
L00094 LABEL NEAR
ENDIF
;
DEC DL ;80 TRIES?
JNZ L00095
JMP ABORT ;YES, ABORT
L00095: JMP WAITNLP ;NO, LOOP
WAITNAK ENDP
;
;
;----> PROCOPT: PROCESS COMMAND OPTIONS
;
;1) SAVES THE PRIMARY OPTION IN 'OPTION';
;2) IF OPTION 'H' (HELP) IS ASKED FOR,
;TRANSFERS DIRECTLY TO THE HELP PRINT;
;3) SCANS THE SUB-OPTION CHARACTERS, AND FOR
;EACH FOUND, ZEROS THE APPROPRIATE ENTRY IN
;THE OPTION TABLE. FOR EXAMPLE, IF 'D' IS
;CODED (DISCONNECT) THEN THE 'D' STORED AT
;'DISCFLG' IS SET TO 0 SO IT CAN BE TESTED
;LATER.
;
PROCOPT PROC NEAR
MOV DX,OFFSET FCBNAME ;TO PRIMARY OPT.
XCHG BX,DX
MOV AL,ES:[BX] ;GET PRIMARY OPT.
XCHG BX,DX
MOV OPTION,AL ;SAVE IT
CMP AL,'X' ;MODEM EXAMPLES?
JNZ L00096
JMP EXAM ;..YES, GIVE EXAMPLES
L00096: CMP AL,'H' ;MODEM H(ELP)?
JNZ OPTLP
JMP HELP ;..YES, GIVE HELP
OPTLP: PUSHF
INC DX ;TO SECONDARY OPTION
POPF
XCHG BX,DX
MOV AL,ES:[BX] ;GET CHAR
XCHG BX,DX
;
;IF YOU MOD THIS PROGRAM FOR >7 OPTIONS,
;YOU MUST CHANGE THE FOLLOWING, SINCE
;THERE WON'T BE A ' ' AFTER THE OPTION
;IF A BAUD RATE WAS SPECIFIED.
;
CMP AL,' ' ;NO MORE OPT'NS?
JNZ L00097
JMP ENDOPT ;..YES
;SET THE APPROP. OPT: STORE 0 IN IT
L00097: MOV BX,OFFSET OPTBL ;HL = ADDR OF 'OAQDSRV'
MOV CX,TABLESIZE ;OPT TABLE LEN
OPTCK: CMP AL,BYTE PTR [BX] ;FOUND THE OPTION?
JZ L00098
JMP OPTNO ;NO, DON'T SET IT
L00098: MOV BYTE PTR [BX],0 ;SET THE OPTION
JMP OPTLP ;GET NEXT OPTION
OPTNO: PUSHF
INC BX
POPF ;TO NEXT
DEC CX ;MORE?
JZ L00099
JMP OPTCK
;OPTION NOT IN TABLE
L00099: JMP BADOPT ;SHOW BAD SUB OPTION
;
ENDOPT: Mov Bx,Offset FCBEXT ; Get address of extentsion
MOV AL,ES:[BX] ;GET CHAR
CMP AL,' ' ;NO MORE OPT'NS?
Jnz Brate ;If so, check specified baud rate
Jmp Endext ;Exit!
;
; This function sets the baud rate.
;
Brate: Mov Si,Offset Bdtab ; Get address of table
Mov Ah,[Si] ; Number entries
Xor Cx,Cx ; Clear count
;
Bloop: Inc Si ; Point to char string
Mov Cl,03h ; Get string count
Mov Di,Bx ; Source string in FCB
Rep Cmpsb ; Check specified baudrate from tbl
Jz Brfnd ; If ok, then we found the baudrate
Bloop1: Inc Si ; Bump pointer
Loop Bloop1 ; Until end of string
Dec Ah ; Bump entry count
Jnz Bloop ; Loop
Mov Al,10h ; Default to 9600
Jmp Bset ; Set bud rate
;
Brfnd: Mov Al,[Si] ; Get new baud rate
;
Bset: Mov Brr,Al ; Save Rx baud rate
Mov Brt,Al ; Save Tx baud rate
Endext: ret
;
;IF "VIEW" WAS ASKED FOR, SET QUIET FLAG
;
MOV AL,VSEEFLG ;VIEW..
OR AL,AL ;..ASKED FOR?
JZ L00100
RET ;..NO, RET FROM 'PROCOPT'
L00100: MOV QFLG,AL ;YES, NO HDR/CKSUM PRT
RET ;FROM 'PROCOPT'
PROCOPT ENDP
;
;DONE - CLOSE UP SHOP
;
DONE PROC NEAR
MOV AL,VSEEFLG ;VIEWING?
OR AL,AL
JNZ L00101
JMP DONETC ;SHOW MSG
L00101: MOV AL,QFLG ;QUIET
OR AL,AL ;..MODE?
JNZ DONETC
JMP DONECTE ;YES, CK TERM/ECHO
DONETC: PUSH BX
MOV BX,OFFSET MSG14
CALL ILPRT
POP BX
;
;CHECK IF TERMINAL OR ECHO SUB COMMAND
;WAS SPECIFIED
;
DONECTE:
MOV AL,TERMFLG ;TERM?
OR AL,AL
JNZ L00103
JMP TERM ;..YES
L00103: MOV AL,ECHOFLG ;ECHO?
OR AL,AL
JNZ CKDIS
JMP TRMECHO ;..YES
;
;FALL INTO 'CKDIS'
;
;----> CKDIS: CHECK IF DISCONNECT REQUESTED
;
;THIS ROUTINE IS JUMPED TO AT THE END OF
;PROCESSING, AND DISCONNECTS THE PHONE IF
;'D' WAS SPECIFIED AS A SUB-OPTION.
;
CKDIS: MOV AL,DISCFLG ;CHECK 'D' FLAG
OR AL,AL ;REQUESTED?
;
;AWAIT C/R TO DISC or space bar to just exit SO WE DON'T LOSE THE PHONE
;
PUSH BX
MOV BX,OFFSET MSG15
CALL ILPRT
POP BX
CALL KEYIN
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH
CALL CRLF
POP AX
XCHG AL,AH
SAHF
CMP AL,20H
JE DISCONN
CMP AL,0DH
JNE CKDIS
;
;----> DISCONN: DISCONNECT THE PHONE
;
MOV BYTE PTR Misc_CCB.Function,14 ; Function - Set modem signals
MOV BYTE PTR Misc_CCB.Character,0 ; Reset all bits
MOV DX,OFFSET Misc_CCB ; Packet at DS:DX
MOV BYTE PTR Misc_CCB.Buffer,1 ; Device number 1
MOV BX,3 ; Handle for Comms
MOV AX,4402H ; IOCTOL function
INT 21H ; Call MS-DOS
DISCONN:
PUSH BX
MOV BX,OFFSET msg16
CALL Ilprt
POP BX
JMP Exit
DONE ENDP
;
;NO DISCONNECT, TYPEZZ MSG AS REMINDER THAT PHONE'S
;ON HOOK
;
;
;----> INITMOD: INITIALIZED THE MODEM
;
;THIS ROUTINE IS USED TO INITIALIZE SERIAL
;PORT USED BY THE PROGRAM.
;
;
;
; INIT COMM PORTS
;
INITMOD PROC NEAR
Mov AX,CS ; Set up Segment and offset
Mov Word Ptr Bsegm,AX ; of our comms. buffer
Mov AX,Offset Comm_buffer ; .
Mov Word Ptr Boff,AX ; ..
;
MOV DX,OFFSET INIT_CCB ; DS:DX points to control block
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
INT 21H ; Call MS-DOS
;
; Here we have to enable the receiver
;
Mov Byte Ptr MISC_CCB.FUNCTION,04 ; Enable receiver
MOV DX,OFFSET MISC_CCB ; DS:DX points to control block
MOV AX,4402H ; IOCTL function program to default
MOV BX,3 ; File handle for comms
INT 21H ; Call MS-DOS
;
; Bring up DTR,RTS and SRTS
;
MOV BYTE PTR Misc_CCB.Function,14 ; Set modem signals
MOV BYTE PTR Misc_CCB.Character,1110B ; DTR, RTS and SRTS.
MOV BYTE PTR Misc_CCB.Buffer,1 ; Comm port
MOV DX,OFFSET Misc_CCB ; Packet at DS:DX
MOV AX,4402H ; Function IOCTL
MOV BX,3 ; Handle for comms
INT 21H ; Call MS-DOS
RET
;
INITMOD ENDP
;
Statit Proc Near
;
; See if there is a character available from the serial port
;
Push Bx ; Save registers
Push Dx
MOV AX,4402H ; IOCTL function input Char.
MOV BX,3 ; File handle for AUX
MOV DX,OFFSET IN_CCB ; DS:DX points to control blk.
INT 21H ; Call MS-DOS
;
Mov Al,BYTE PTR IN_CCB.RETURN_CODE ; Did we get a character?
Pop Dx ; Restore registers
Pop Bx
Ret ; Exit
;
Statit Endp
;
Getit Proc Near
;
MOV AL,BYTE PTR IN_CCB.CHARACTER ; GET CHAR
Ret
;
Getit Endp
;
; On Entry:
; Al = Character
;
; On Exit:
; Ah = Status
; FFh - Character sent
; 00h - Character not sent
; Al = Character
;
Sendit Proc Near
;
; Output character to serial port using MS-DOS IOCTL
;
Push Bx ; Save Register
Push Dx
;
MOV BYTE PTR OUT_CCB.CHARACTER,AL ; Character in control block
MOV AX,4402H ; IOCTL function out
MOV BX,3 ; Handle for AUX
MOV DX,OFFSET OUT_CCB ; DS:DX points to control block
INT 21H ; Call MS-DOS
;
Mov Ah,Out_CCB.Return_code ; Get status of operation
Mov Al,Out_CCB.Character ; Get character sent
Pop Dx ; Restore registers
Pop Bx
Ret
;
Sendit Endp
;
;
;----> MOVEFCB: MOVES FCB(2) TO FCB
;
;I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL',
;I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER
;THAT MODEM FILENAME SEND (MODEM FN.FT S) SO THIS
;ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
;TO THE FIRST
;
MOVEFCB PROC NEAR
MOV BX,OFFSET FCB2 ;FROM
MOV DX,OFFSET FCB ;TO
MOV CH,16 ;LEN
PUSH DS ;SAVE DS
PUSH ES ;MOVE ES ...
POP DS ;... TO DS
CALL MOVE ;DO THE MOVE
POP DS ;RESTORE DS
XOR AL,AL ;GET 0
MOV FCBCR,AL ;ZERO CURRENT RECORD
MOV FCBRR,AL ;..AND RANDOM RECORD
RET
MOVEFCB ENDP
;
;----> SHOW: SHOWS CHAR SENT/RECEIVED
;
;CR, LF, AND TAB ARE SHOWN. ALL OTHER
;NON-PRINTABLE CHARACTERS ARE SHOWN IN
;HEX AS (XX)
;
SHOW PROC NEAR
CMP AL,LF ;LF?
JNZ L00122
JMP CTYPEZZ ;..YES, TYPEZZ IT
L00122: CMP AL,CR ;CR?
JNZ L00123
JMP CTYPEZZ ;..YES, TYPEZZ IT
L00123: CMP AL,09 ;TAB
JNZ L00124
JMP CTYPEZZ ;..YES, TYPEZZ IT
L00124: CMP AL,' ' ;CTL-CHR?
JAE L00125
JMP SHOWHEX ;YES, SHOW IN HEX
L00125: CMP AL,7FH ;DEL?
JAE SHOWHEX
JMP CTYPEZZ ;NO, TYPEZZ THE CHAR
SHOWHEX LABEL NEAR
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;SAVE THE CHAR
MOV AL,'(' ;TYPEZZ..
CALL CTYPEZZ ;..'('
POP AX
XCHG AL,AH
SAHF ;THEN..
CALL HEXO ;..THE CHAR
MOV AL,')' ;THEN..
JMP CTYPEZZ ;..')' AND RETURN.
;
;----> CTYPEZZ: TYPEZZS VIA CP/M SO TABS ARE EXPANDED
;
CTYPEZZ LABEL NEAR
PUSH CX ;SAVE..
PUSH DX ;..ALL..
PUSH BX ;..REGS
MOV DL,AL ;CHAR TO E
MOV CL,WRCON ;GET BDOS FNC
CALL BDOS ;PRIN THE CHR
POP BX ;RESTORE..
POP DX ;..ALL..
POP CX ;..REGS
RET ;FROM "CTYPEZZ"
SHOW ENDP
;
CRLF PROC NEAR
MOV AL,CR
CALL TYPEZZ
MOV AL,LF
CRLF ENDP
;
;----> TYPEZZ: TYPEZZ VIA DIRECT BDOS ACCESS
;
;THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C
;TESTS.
;
TYPEZZ PROC NEAR
;
; Now we output the character to the display using the firmware
;
PUSH AX ; save char
PUSH Di
XOR DI,DI ; output to console
INT ROM
Pop Di
POP AX ; restore char
RET ;FROM "TYPEZZ"
TYPEZZ ENDP
;
;KEYBOARD STATUS
;
; This routine has been changed from CP/M-86: the service for
; MS-DOS differs in several respects.. [CP/M version uses
; x'FE' in DL and calls "DCON" which isn't supported
; in MSDOS .. SO we use the direct bios call.
;
;
STAT PROC NEAR
Push Cx ; Save register
Push Di
MOV DI,4 ; Get console status
INT ROM
Mov Al,Cl ; Get status
OR AL,AL ;0 => NOT READY
Pop Di ; Restore registers
Pop Cx
RET
STAT ENDP
;
;KEYBOARD INPUT
;
; This routine has been changed to use direct BIOS interface.
; CTRL-C sequences are intercepted and interpreted as
; termination requests
;
KEYIN PROC NEAR
Push Bx
Push Cx ; Save registers
Push Di
Keylp: MOV DI,2 ; input from KEYBOARD
INT ROM
Or CL,CL
JZ Keylp ; skip if no input
;
CMP AL,CTLCCHR ; Was it a "Control-C"
JNE Keyext ; If not, exit
MOV AL,CTLCHAR ; Substitute a real ^C
;
Keyext: Pop Di ; Restore registers
Pop Cx
Pop Bx
Ret
KEYIN ENDP
;
;HEX OUTPUT
;
HEXO PROC NEAR
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH ;SAVE FOR RIGHT DIGIT
RCR AL,1 ;RIGHT..
RCR AL,1 ;..JUSTIFY..
RCR AL,1 ;..LEFT..
RCR AL,1 ;..DIGIT..
CALL NIBBL ;PRINT LEFT DIGIT
POP AX
XCHG AL,AH
SAHF ;RESTORE RIGHT
NIBBL: AND AL,0FH ;ISOLATE DIGIT
CMP AL,10 ;IS IS <10?
JAE L00127
JMP ISNUM ;YES, NOT ALPHA
L00127: ADD AL,7 ;ADD ALPHA BIAS
ISNUM: ADD AL,'0' ;MAKE PRINTABLE
JMP TYPEZZ ;..THEN TYPEZZ IT
HEXO ENDP
;
;----> CKQUIT: QUIT/RETRY AFTER MULTIPLE ERRS.
;
;RETURNS W/ ZERO SET IF "RETRY" ASKED FOR
;
CKQUIT PROC NEAR
XOR AL,AL ;ZERO..
MOV ERRCT,AL ;..ERROR COUNT
PUSH BX
MOV BX,OFFSET MSG18
CALL ILPRT ;PRINT:
POP BX
CALL KEYIN ;QUIT/RETRY
LAHF
XCHG AL,AH
PUSH AX
XCHG AL,AH
CALL CRLF
POP AX
XCHG AL,AH
SAHF
AND AL,5FH ;MAKE UPPER CASE
CMP AL,'R' ;RETRY?
JNZ L00128
RET ;'KEEP ON TRUCKIN'
L00128: CMP AL,'Q' ;QUIT?
JZ L00129
JMP CKQUIT ;NO, ASK AGAIN
L00129: OR AL,AL ;SET NON-ZERO
RET
CKQUIT ENDP
;
;----> ILPRT: INLINE PRINT OF MSG
;
;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
;BINARY 0 AS THE END. BINARY 1 MAY BE USED TO
;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
;
ILPRT PROC NEAR
ILPLP: MOV AL,BYTE PTR[BX]
OR AL,AL ;END OF MSG?
JNZ L00130
JMP ILPRET ;..YES, RETURN
L00130: CMP AL,1 ;PAUSE?
JNZ L00131
JMP ILPAUSE ;..YES
L00131: CALL CTYPEZZ ;TYPEZZ THE MSG
ILPNEXT:
PUSHF
INC BX
POPF ;TO NEXT CHAR
JMP ILPLP ;LOOP
;
;PAUSE WHILE TYPING HELP SO INFO DOESN'T
; SCROLL OFF OF VIDEO SCREENS
;
ILPAUSE:
PUSH BX
MOV BX,OFFSET MSG19
CALL ILPRT ;PRINT:
POP BX
CALL KEYIN ;GET ANY CHAR
CMP AL,'C'-40H ;REBOOT?
JNZ L09132 ;EXIT IF QUITCHAR
JMP EXIT
L09132: CMP AL,'I'-40H ;ALT REBOOT?
JNZ L00132 ;
JMP EXIT ;YES.
L00132: JMP ILPNEXT ;LOOP
ILPRET: RET ;PAST MSG
ILPRT ENDP
;
;----> PRTMSG: PRINTS MSG POINTED TO BY (DE)
;
;A '$' IS THE ENDING DELIMITER FOR THE PRINT.
;NO REGISTERS SAVED.
;
PRTMSG PROC NEAR
MOV CL,PRINT ;GET BDOS FNC
JMP BDOS ;PRINT MESSAGE, RETURN
PRTMSG ENDP
;
;----> ERXIT: EXIT PRINTING MSG FOLLOWING CALL
;
ERXIT PROC NEAR
POP BX ;GET MESSAGE
CALL PRTMSG ;PRINT IT
CALL CKDIS ;DISCONNECT?
JMP EXIT ;RETURN TO PC DOS
ERXIT ENDP
;
;MOVE 128 CHARACTERS
;
MOVE128 PROC NEAR
MOV CH,128 ;SET MOVE COUNT
;
;MOVE FROM (HL) TO (DE) LENGTH IN (B)
;
MOVE: MOV AL,BYTE PTR [BX] ;GET A CHAR
XCHG BX,DX
MOV [BX],AL
XCHG BX,DX ;STORE IT
PUSHF
INC BX
POPF ;TO NEXT "FROM"
PUSHF
INC DX
POPF ;TO NEXT "TO"
DEC CH ;MORE?
JZ L00133
JMP MOVE ;..YES, LOOP
L00133: RET ;..NO, RETURN
MOVE128 ENDP
;
BDOS PROC NEAR
PUSH BX
PUSH CX
PUSH DX
MOV AH,CL ;MOVE FNC FOR PC DOS
INT 21H ;INVOKE MS-DOS
POP DX
POP CX
POP BX
RET
BDOS ENDP
;
BADOPT: CALL TYPEZZ
PUSH BX
MOV BX,OFFSET MSG25
CALL ILPRT
POP BX
HELP: PUSH BX
MOV BX,OFFSET MSG26
CALL ILPRT
POP BX
JMP copyrt
EXAM: PUSH BX
MOV BX,OFFSET MSG27
CALL ILPRT
POP BX
JMP copyrt
;
; Print Limited license with "HELP" request output
;
copyrt: CALL STAT
;
; CLEAR THE SCREEN (cursor = 1,1)
;
;
; PRINT COPYRIGHT NOTICE AND PAUSE
;
mov bx,offset msg00 ;point to copyright notice
call ilprt ; go print it (PAUSE)
;
; RETURN TO CALLER
;
jmp exit
;
Comm_Buffer Label Word
;
;
MODEM ENDS
SUBTTL 'MODIFICATION HISTORY AND CREDITS'
PAGE
;
;* * * * * * * * * * * * * * * * * * * * * * * * *
;* *
;* THIS PROGRAM DOCUMENTED IN "MODEM.DOC" *
;* *
;* * * * * * * * * * * * * * * * * * * * * * * * *
;* THIS PROGRAM WAS "MODEM.ASM" BUT and then was *
;* TEMPORARILY NAMED "MODEM2.ASM" SO PEOPLE *
;* WILL REALIZE IT IS AN ENHANCEMENT OF *
;* THE ORIGINAL PROGRAM "MODEM.ASM" ON CP/M *
;* USER'S GROUP DISK 25. *
;* * * * * * * * * * * * * * * * * * * * * * * * *
;
;PLEASE PASS ON MODS, BUGS, ETC, SO YOUR
;FIXES OR ENHANCEMENTS MAY BE SHARED BY ALL,
;
;Please send to the bottom name on the list,
; OR TO ALL OF US - if you can afford
; the time
;
; Ward Christensen
; 688 E. 154th St. #5D
; Dolton, Il. 60419
;
; (312) 849-6279
;
;You may send a self-addressed stamped postcard
;to be informed of changes/bugs as they become
;known. [CP/M Version]
;
;
;
; 05/08/82
;Modified for CP/M 86 and the IBM PC
; by Randy Suess
; 5219 Warwick
; Chicago, Ill 60641
; 312-545 7535
;
; 06/03/82
;Modified for PC DOS and the IBM PC
;by Rick Mallinak
; 22451 Franklin Dr.
; Richton Park, Ill 60471
; (312) 481-6459
;
; 08/11/82
;Repaired for PC DOS 1.1 and IBM PC
;by John Chapman
; 844 S. Madison St.
; Hinsdale Illinois 60521
; (312) 325-3081
; CS: 70205,1217
;
;
;
; --------------------
; MODIFICATION HISTORY
; --------------------
;
; 09/23/77
;ORIGINALLY WRITTEN BY WARD CHRISTENSEN
;
; 04/26/79
;REWRITTEN BY WARD CHRISTENSEN TO COMBINE
;IMPROVEMENTS TO THE ORIGINAL MADE BY WARD
;AND BY KEITH PETERSEN, W8SDZ, AND SUGGESTIONS
;BY JIM BELL WHICH KEITH IMPLEMENTED. SEE
;MODEM.DOC FOR ADDITIONAL HISTORICAL
;INFORMATION AND DOCUMENSATION.
;
; 05/09/79
;ALLOW 'T' AND 'E' SUB-OPTIONS TO GO TO TERMINAL
;OR ECHO MODEM AFTER TRANSFERRING A FILE. (WLC)
;
; 05/22/79
;ADD FEATURE TO MAKE RECEIVE FILE ROUTINE SAY
;FILE SUCCESSFULLY OPENED, WHEN IN QUIET MODE.
;MOVE INITIAL GOBBLE GARBAGE INPUTS TO BEFORE
;COMMAND CPI'S SO ALL MODES ARE CLEARED. CHANGE
;INITIAL SEND WAIT TO 80 SECS TO ALLOW MORE TIME
;FOR RECEIVING END TO COME UP. ADD 'H' AFTER MSG
;THAT SHOWS NUMBER OF SECTORS IN EXTENT ABOUT TO
;BE SENT. (KBP)
;
; 05/24/79
;FIX MISSING RETURN INSTRUCTION AT END OF
;INITIALIZATION ROUTINE. (KBP)
;
; 07/13/79
;PUT IN RESET OF DMA ADDR TO 80H AFTER
;FILE RECEIVE, BECAUSE "SUBMIT" UNDER CP/M
;DOESN'T RESET IT BEFORE READING THE
;NEXT SUBMITTED COMMAND. /// ALSO DELETE
;CODE FOR "CANCEL" AS IT'S JUST TOO EASY
;TO INTENTIONALLY GET A CANCEL AS A
;GARBAGED LINE CHARACTER.
;
;
;
; 05/82
;
;Rewritten for CP/M-86 by Randy Suess
;Changes mainly to interface with
;the CP/M-86 BDOS services
;
; 06/82
;
;Randy's version altered by Rick Mallinak
;to be acceptable to PC/DOS assembler.
;Comments added and changes made to
;support multiple segment version
;
; 08/82
;
;Rick's PC/DOS version reworked
;to: a) Run as a .COM file by
;returning to single segment image;
;b) terminal bugs repaired,; c) code
;added to 'bring up' DTR as program
;starts up [necessary for non-autodial
;commercial modems].
;
; 01/84
;
;Version 3.3 of modem for the RAINBOW was
;converted from the IBM-PC implementation by
;Jim Colombo, DEC - RAINBOW SOFTWARE GROUP
;with the additional feature of specifing the
;baud rate on the command line. Version 3.3.1
;changes the way modem sends character using the
;IOCTL function. The Transmitter now uses function
;10 (Send character, return is unsuccessful) and
;the character is queued if the character wasn't
;sent.
;
;
; 10/84
;Version 3.3.2 fixes bug with sending files less
;than 15 sectors in length. If the MS/DOS sequential
;read (INT 21H, AH = 14H) function returns a partial
;read error (3), then that sector must also be sent!
;Also fixed bug with KEYIN trashing the BX register.
;
; 10/84
;Version 3.3.3 Added improved control of DTR on exit and cleaned
;up comments.
;
; 01/18/85
;Version 3.3.4 Reset comm port to NVM values on exit.
; Marshall Goldberg.
;
END MAIN